# -*- coding: cp936 -*-
import sys
perr = sys.stderr

def abbrev(astring, maxlen=10):
    if len(astring) > maxlen:
        return astring[0:10]
    return astring

def impPickle():
    try: tmp = __import__("cPickle")
    except: tmp = __import__("pickle")
    return tmp

def id2Obj(id_):
    """
    >>> id2Obj(id([1,2,3])) == [1,2,3]
    True
    """
    import ctypes
    return ctypes.cast(ctypes.c_void_p(id_), ctypes.py_object).value

###-------------------------------------###
###### HashLib Stack Impl. and Test  ######
###-------------------------------------###

def str2File(astr, filename):
    with file(filename, "w") as wf:
        wf.write(astr)
    return wf

def file2Strs(filename):
    with file(filename, "r") as rf:
        for line in rf.readlines():
            yield line

import lxs
calFileHash = lxs.calFileHash
md5 = lxs.md5
sha1 = lxs.sha1

def sortStrWithPatGroupNo(patWithGroup1, alist, groupNo=1):
    """
    >>> print sortStrWithPatGroupNo(r"data([0-9]+).in", ["data10.in", "data11.in", "data1.in", "data.in"])
    ['data1.in', 'data10.in', 'data11.in']
    """
    import re
    pat = re.compile(patWithGroup1)
    ans = []
    for l in alist:
         s = pat.match(l)
         if (s == None): continue
         if (s.group() == l):
             ans.append((int(s.group(groupNo)), s.group(0)))
    ans.sort()
    return [v for n, v in ans]


########################################################
########################################################
########################################################

import sys
class ostream:
    def __init__(self, file):
        self.file = file
    def __lshift__(self, obj):
        self.file.write(str(obj))
        return self
    @classmethod
    def getOut(self):
        return ostream(sys.stdout)
    @classmethod
    def getErr(self):
        return ostream(sys.stderr)
cout = ostream.getOut()
cerr = ostream.getErr()
endl = "\n"

### Why not combine them together?
def none(iterable):
    for i in iterable:
        if i == True: return False
    return True

def nonef(iterable, fun):
    for i in iterable:
        if fun(i) == True: return False
    return True

def anyf(iterable):
    for i in iterable:
        if fun(i) == True: return True
    return False

def allf(iterable):
    for i in iterable:
        if fun(i) == False: return False
    return True

def minid(*iterable):
    if len(iterable) == 1:
        it = iter(iterable[0])
    else:
        it = iter(iterable)
    besti, bestv = 0, it.next()
    for i,v in enumerate(it, 1):
        if v < bestv: besti, bestv = i, v
    return besti, bestv

def utc_timestamp():
    import time
    return time.strftime('%Y%m%d%H%M%S',time.gmtime())


astr = "12313123"

def fun():
    import time
    time.sleep(2)
    import random
    return astr + random.randInt(3)

def wrap(queue, work):
    queue.put(work())

def complishInTimeOrTerminated(work, timeout):
    import multiprocessing as m
    q = m.Queue()
##    import Queue
##    q = Queue.Queue()
    p = m.Process(target=wrap, args=(q, work))
    p.start()
    p.join(timeout)
    if (q.empty()):
        ret = None
        p.terminate()
    else: ret = q.get()
    return ret
    
def testComplishInTimeOrTerminated():
    import time
    a = time.time()
    ans = complishInTimeOrTerminated(fun, 3)
    print time.time() - a
    print ans

### Exception Free Design

def printOut(ex):
    import sys
    print >>sys.stderr, ex

def sysOut(ex):
    print ex

def exhandle(func_obj, exfunc = printOut):
    """
    >>> exhandle(lambda:shutil.move(logfile, os.path.join(log_tmp, ".la.log")), sysOut)
    global name 'shutil' is not defined
    """
    import types
    if (type(func_obj) is types.FunctionType) == False :
        raise TypeError("Expected FunctionType but get " + str(type(func_obj)) + " instead.")
    try:
        return func_obj()
    except Exception as ex:
        exfunc(ex)

class ExceptionHandler(object):
    """
    >>> eh = ExceptionHandler(sysOut)
    >>> eh << [lambda : shutil.move(logfile, os.path.join(log_tmp, ".la.log")),lambda : shutil.move(hup, os.path.join(log_tmp, jarfile + ".nohup.log")),lambda : shutil.copyfile(domain_log, os.path.join(log_tmp, jarfile + ".domain.log"))]
    global name 'shutil' is not defined
    global name 'shutil' is not defined
    global name 'shutil' is not defined
    """
    def __init__(self, exception_handle_func = printOut):
        self.exception_handle_func = exception_handle_func
        
    def __lshift__(self, func_list):
        for func in func_list:
            self.catch(func)
            
    def catch(self, func):
        return exhandle(func, self.exception_handle_func)

    def __call__(self, *func_list):
        for func in func_list:
            self.catch(func)
        

    @staticmethod
    def ins():
        if ((hasattr(ExceptionHandler, "a") == False) or (ExceptionHandler.singleton == None)):
            ExceptionHandler.singleton = ExceptionHandler()
        return ExceptionHandler.singleton


def ExceptionBlock(exfunc = printOut):
    """
    >>> func()
    Very wrong.
    """
    def func(method):
        def ex_handle_method(*args, **kws):
            return exhandle(method, exfunc)
        return ex_handle_method
    return func

@ExceptionBlock(lambda e:sys.stdout.write(str(e) + "\n"))
def func():
    raise Exception("Very wrong.")

class attrDict(object):
    """
    >>> a = attrDict()
    >>> a.abc = 1
    >>> a.abc
    1
    """
    def __init__(self):
        self.__inner_dict__ = dict()
##    def __getattribute__(self, name):
##        if hasattr(self, name) == False:
##            super.__setattr__(name, None)
##        return super.__getattribute__(name)
    def __setattr__(self, name, value):
        super.__setattr__(self, name, value)
        if (name != "__inner_dict__"):
            self.__inner_dict__[name] = value

    def getDict(self):
        return self.__inner_dict__    

if __name__ == "__main__":
    import doctest
    doctest.testmod()
    print "--- lxu.py ---"

    testComplishInTimeOrTerminated()
